#include "string.h"
#include "exfuns.h"
#include "fattester.h"
#include "rtthread.h"
#include "fontupd.h"
#define FILE_MAX_TYPE_NUM 7 //最多FILE_MAX_TYPE_NUM个大类
#define FILE_MAX_SUBT_NUM 4 //最多FILE_MAX_SUBT_NUM个小类

//文件类型列表
const u8 *FILE_TYPE_TBL[6][13] =
	{
		{"BIN"},																					  //BIN文件
		{"LRC"},																					  //LRC文件
		{"NES"},																					  //NES文件
		{"TXT", "C", "H"},																			  //文本文件
		{"MP1", "MP2", "MP3", "MP4", "M4A", "3GP", "3G2", "OGG", "ACC", "WMA", "WAV", "MID", "FLAC"}, //音乐文件
		{"BMP", "JPG", "JPEG", "GIF"},																  //图片文件
};
///////////////////////////////公共文件区,使用malloc的时候////////////////////////////////////////////
FATFS *fs[2];	  //逻辑磁盘工作区.
FIL *file;		  //文件1
FIL *ftemp;		  //文件2.
UINT br, bw;	  //读写变量
FILINFO fileinfo; //文件信息
DIR dir;		  //目录

u8 *fatbuf; //SD卡数据缓存区
///////////////////////////////////////////////////////////////////////////////////////
//为exfuns申请内存
//返回值:0,成功
//1,失败
u8 exfuns_init(void)
{
	fs[0] = (FATFS *)rt_malloc(sizeof(FATFS)); //为磁盘0工作区申请内存
	fs[1] = (FATFS *)rt_malloc(sizeof(FATFS)); //为磁盘1工作区申请内存
	file = (FIL *)rt_malloc(sizeof(FIL));	   //为file申请内存
	ftemp = (FIL *)rt_malloc(sizeof(FIL));	   //为ftemp申请内存
	fatbuf = (u8 *)rt_malloc(512);			   //为fatbuf申请内存
	if (fs[0] && fs[1] && file && ftemp && fatbuf)
		return 0; //申请有一个失败,即失败.
	else
		return 1;
}

//将小写字母转为大写字母,如果是数字,则保持不变.
u8 char_upper(u8 c)
{
	if (c < 'A')
		return c; //数字,保持不变.
	if (c >= 'a')
		return c - 0x20; //变为大写.
	else
		return c; //大写,保持不变
}
//报告文件的类型
//fname:文件名
//返回值:0XFF,表示无法识别的文件类型编号.
//		 其他,高四位表示所属大类,低四位表示所属小类.
u8 f_typetell(u8 *fname)
{
	u8 tbuf[5];
	u8 *attr = '\0'; //后缀名
	u8 i = 0, j;
	while (i < 250)
	{
		i++;
		if (*fname == '\0')
			break; //偏移到了最后了.
		fname++;
	}
	if (i == 250)
		return 0XFF;		//错误的字符串.
	for (i = 0; i < 5; i++) //得到后缀名
	{
		fname--;
		if (*fname == '.')
		{
			fname++;
			attr = fname;
			break;
		}
	}
	strcpy((char *)tbuf, (const char *)attr); //copy
	for (i = 0; i < 4; i++)
		tbuf[i] = char_upper(tbuf[i]); //全部变为大写
	for (i = 0; i < 6; i++)
	{
		for (j = 0; j < 13; j++)
		{
			if (*FILE_TYPE_TBL[i][j] == 0)
				break;																//此组已经没有可对比的成员了.
			if (strcmp((const char *)FILE_TYPE_TBL[i][j], (const char *)tbuf) == 0) //找到了
			{
				return (i << 4) | j;
			}
		}
	}
	return 0XFF; //没找到
}

//得到磁盘剩余容量
//drv:磁盘编号("0:"/"1:")
//total:总容量	 （单位KB）
//free:剩余容量	 （单位KB）
//返回值:0,正常.其他,错误代码
u8 exf_getfree(u8 *drv, u32 *total, u32 *free)
{
	FATFS *fs1;
	u8 res;
	u32 fre_clust = 0, fre_sect = 0, tot_sect = 0;
	//得到磁盘信息及空闲簇数量
	res = (u32)f_getfree((const TCHAR *)drv, (DWORD *)&fre_clust, &fs1);
	if (res == 0)
	{
		tot_sect = (fs1->n_fatent - 2) * fs1->csize; //得到总扇区数
		fre_sect = fre_clust * fs1->csize;			 //得到空闲扇区数
#if _MAX_SS != 512									 //扇区大小不是512字节,则转换为512字节
		tot_sect *= fs1->ssize / 512;
		fre_sect *= fs1->ssize / 512;
#endif
		*total = tot_sect >> 1; //单位为KB
		*free = fre_sect >> 1;	//单位为KB
	}
	return res;
}
/**
 * @brief :文件系统初始化，包括初始化SD卡和flash，并检查字库完整性,如果有初始化失败则堵塞
 * @param {*}
 * @return {*}
 */
void fileSystemInit()
{
	u32 total, free;
	u8 key, t;



	while (SD_Init()) //检测SD卡
	{
		printf("SD Card Failed!\n");
		delay_ms(200);
		delay_ms(200);
	}
	exfuns_init(); //为fatfs相关变量申请内存

	f_mount(fs[0], "0:", 1);		   //挂载SD卡
	int res = f_mount(fs[1], "1:", 1); //挂载FLASH.

	while (font_init()) //检查字库
	{
	UPD:
		while (SD_Init()) //检测SD卡
		{
			printf("SD Card Failed!\n");
			delay_ms(200);
			delay_ms(200);
		}
		printf("SD Card OK\n");
		printf("Font Updating...\n");
		key = update_font(20, 110, 16, "0:"); //更新字库
		while (key)							  //更新失败
		{
			printf("Font Update Failed!\n");
			delay_ms(200);
			delay_ms(200);
		}
		printf("Font Update Success!   \n");
		delay_ms(1500);
	}

	while (exf_getfree("0:", &total, &free))
	{
		printf("SD Card Fatfs Error!\n");
		delay_ms(200);
		delay_ms(200);
	}

	printf("SD Card FATFS OK!\n");
	printf("SD Total Size:  %d MB ,%d KB\n", total >> 10, total);
	printf("SD Free Size:  %d MB  ,%d KB\n", free >> 10, free);

	while (exf_getfree("1:", &total, &free))
	{
		printf("flash Fatfs Error!\n");
		delay_ms(200);
		delay_ms(200);
	}
	printf("flash FATFS OK!\n");
	printf("flash Total Size:  %d MB,%d KB\n", total >> 10, total);
	printf("flash  Free Size:  %d MB,%d KB\n", free >> 10, free);
}